package com.ccrfid.rmc6.service.business.chongqing;

import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.business.chongqing.CQPatrolLocationEntity;
import com.ccrfid.rmc6.entity.business.chongqing.CQPatrolRecordEntity;
import com.ccrfid.rmc6.entity.business.chongqing.CQPatrolRoadEntity;
import com.ccrfid.rmc6.entity.poi.PoiLocationEntity;
import com.ccrfid.rmc6.repository.business.chongqing.CQPatrolLocationRepository;
import com.ccrfid.rmc6.repository.business.chongqing.CQPatrolRecordRepository;
import com.ccrfid.rmc6.repository.business.chongqing.CQPatrolRoadRepository;
import com.ccrfid.rmc6.repository.poi.PoiLocationRepository;
import com.ccrfid.rmc6.repository.search.SearchCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class CQPatrolServiceImpl implements CQPatrolService {

    @Autowired
    private PoiLocationRepository poiLocationRepository;
    @Autowired
    private CQPatrolRoadRepository patrolRoadRepository;
    @Autowired
    private CQPatrolRecordRepository patrolRecordRepository;
    @Autowired
    private CQPatrolLocationRepository patrolLocationRepository;

    @Override
    public Page<CQPatrolRoadEntity> getCQPatrolRoadPage(SearchCriteria criteria, Pageable pageable) {
        return patrolRoadRepository.search(criteria, pageable);
    }

    @Override
    public List<CQPatrolRoadEntity> getAllCQPatrolRoadList() {
        return patrolRoadRepository.getAllBy();
    }

    @Override
    public CQPatrolRoadEntity getCQPatrolRoadById(Long roadId) {
        return patrolRoadRepository.getById(roadId);
    }

    @Override
    public CQPatrolRoadEntity createCQPatrolRoad(CQPatrolRoadEntity entity) throws AppException {
        if (StringUtils.isEmpty(entity.getRoadName())) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.patrol_road_name_is_null.getCode(), CustomErrors.patrol_road_name_is_null.getReason(), "");
        }
        entity.setId(null);
        return patrolRoadRepository.save(entity);
    }

    @Override
    public CQPatrolRoadEntity updateCQPatrolRoad(Long roadId, CQPatrolRoadEntity entity) throws AppException {
        if (!patrolRoadRepository.existsById(roadId)) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        if (StringUtils.isEmpty(entity.getRoadName())) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.patrol_road_name_is_null.getCode(), CustomErrors.patrol_road_name_is_null.getReason(), "");
        }
        entity.setId(roadId);
        return patrolRoadRepository.save(entity);
    }

    @Override
    public boolean deleteCQPatrolRoad(Long roadId) throws AppException {
        if (!patrolRoadRepository.existsById(roadId)) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        if (patrolLocationRepository.existsByPatrolRoadId(roadId)) {
            patrolLocationRepository.deleteAllByPatrolRoadId(roadId);
        }
        if (patrolRoadRepository.existsById(roadId)) {
            patrolRoadRepository.deleteById(roadId);
        }
        return true;
    }

    @Override
    public List<PoiLocationEntity> getFreePatrolLocationList() {
        List<CQPatrolLocationEntity> list = patrolLocationRepository.getAllBy();
        if (list != null && list.size() > 0) {
            Set<Long> idSet = list.stream()
                    .mapToLong(CQPatrolLocationEntity::getLocationId)
                    .boxed()
                    .collect(Collectors.toSet());
            return poiLocationRepository.getAllByFloorNumberAndIdNotIn(2, idSet);
        } else {
            return poiLocationRepository.getAllByFloorNumber(2);
        }
    }

    @Override
    public List<CQPatrolLocationEntity> getCQPatrolLocationList(Long roadId) {
        return patrolLocationRepository.getAllByPatrolRoadIdOrderById(roadId);
    }

    @Override
    public CQPatrolLocationEntity createCQPatrolLocation(Long roadId, Long locationId) throws AppException {
        if (!patrolRoadRepository.existsById(roadId)) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        if (!poiLocationRepository.existsById(locationId)) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        PoiLocationEntity locationEntity = poiLocationRepository.getById(locationId);
        CQPatrolLocationEntity entity = new CQPatrolLocationEntity();
        entity.setPatrolRoadId(roadId);
        entity.setLocationId(locationId);
        entity.setLocationName(locationEntity.getLocationName());
        entity.setLocationSn(locationEntity.getLocationSn());
        return patrolLocationRepository.save(entity);
    }

    @Override
    public boolean deleteCQPatrolLocation(Long roadId, Long locationId) throws AppException {
        if (patrolLocationRepository.existsByPatrolRoadIdAndLocationId(roadId, locationId)) {
            patrolLocationRepository.deleteByPatrolRoadIdAndLocationId(roadId, locationId);
        } else {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        }
        return true;
    }

    @Override
    public Page<CQPatrolRecordEntity> getCQPatrolRecordPage(SearchCriteria criteria, Pageable pageable) {
        return patrolRecordRepository.search(criteria, pageable);
    }

    @Override
    public CQPatrolRecordEntity saveCQPatrolRecord(CQPatrolRecordEntity entity) {
        return patrolRecordRepository.save(entity);
    }

    @Override
    public CQPatrolRecordEntity getPatrolRecordByRoadIdMax(Long roadId) {
        return patrolRecordRepository.getTopByPatrolRoadIdOrderByIdDesc(roadId);
    }

    @Override
    public List<CQPatrolRecordEntity> getAllPatrolRecordByTask(String task) {
        return patrolRecordRepository.getAllByTaskOrderById(task);
    }
}
